/* The general-purpose event handler. This function just determines the mouse 
   position relative to the canvas element. It is the key fucntion for capturing
   the correct coordinates for the paited object. The event is bound to the canvas
   itself, which is not rotated. I rotate the div contained of the canvas itself!
   Additionally, the key is to use CSS pixels to read the mouse position. That will
   give you always the right coordinates regardless what CSS transformation is applied.
   Attention, apply CSS transformation only, everything else is trasforming the data, 
   which is what is definitively dont want to get.
   The only operation that must happen to logged coordinates is the scalling based
   on the scalling used to generate the image. You can do this operation before
   uploading to archive server, you don't need to to place the annotation.
*/
function ev_canvas (ev) {
// <<<
	if (! ev.hasOwnProperty('offsetX')) {
		var curleft = curtop = 0;
		if (ev.offsetParent) {
			var obj=ev;
			do {
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			} while (obj = obj.offsetParent);
		}
		ev.offsetX=ev.layerX-curleft;
		ev.offsetY=ev.layerY-curtop;
	}
	
	if (ev.offsetX || ev.offsetX == 0) { // Opera || Maxthron || Chrome || IE10 are OK. Mozila not tested yet.
		ev._x = ev.offsetX;
		ev._y = (ev.offsetY );
	} else {
		console.err("Cannot determine the mouse ccordinates");
		return;
	}
		
	// Call the event handler of the pencil tool to draw.
	var func = opentext.drawing.tools.pencil[ev.type];
	if( typeof func == 'function' ) {
		func.call( opentext.drawing.tools.pencil, ev, function() { 
			console.log( "Call back function about to call" );
			opentext.drawing.tools.pencil.doLine(); 
		});
	} else {
		console.error("reflection did not work.");
	}
}	
// >>>

// Define the application namespace.
var opentext = {}; 

// Localization object
opentext.localization = (function() {
// <<<
	return {
		"MSGID000": "Test Message<br/>This is the testing message only, for localization purposes",
		"MSGID001": "Cross-Domain scripting is not allowed<br/>Application cannot retrieve document properties",
		"MSGID002": "Illegal response from server<br/>The response from the server cannot be parsed.",
		"MSGID003":	"Cannot retrieve document properties<br/>The application cannot retrieve document properties",
		"MSGID004": "Cannot create HTML5 element &lt;CANVAS&gt;<br/>Your browser does not seem to support HTML5 elements",
		"MSGID005": "Container element for image data is not defined.",
		"MSGID006": "Image container for the magnifier was created but contains no valid image data.",
		"MSGID007": "The magnifier data are not loaded correctly. Image information missing.",
		"MSGID008": "Cannot create viewer object, invalid archivelink data",
		"MSGID009": "Cannot place viewer object in the document. Given container ID does not exist.",
		"MSGID010": "The canvas does not exist. Cannot place content on non-existent canvas.",
		"MSGID011": "You are already on the first/last page of the document",
		"MSGID012": "Cannot display about dialog.",
		"MSGID013": "Unable to open document",
		"MSGID014": "Either the file format is not supported or <br/>server problems occurred when opening the document.",
		"MSGID015": "Close"
	};
}());
// >>>

// This painting object works like a drawing pencil which tracks the mouse movements.
// The mouse movement is stored in a contained inside the object itself. The data
// gets removed by each initilization cycle and by each use.
opentext.drawingTools = {};
opentext.drawingTools.FreehandTool = function( cnv, ctx ) {
// <<<
	var tool = this;
	tool.conf = {
		started: false,
		canvas: cnv,
		context: ctx,
		anno: [], // contained for annotation. Technically it is array of arrays. 
		anno_counter: 0 // count how many annotations were put on the drawing.
	};
	return {
		conf: this.conf,

		redrawMyAnnotation: function() {
			var tool = this;
			var an;
			var el;
			if( typeof tool.conf.anno == "undefined" )
				return;
	
			tool.conf.context.globalAlpha= "1.0";
			tool.conf.context.strokeStyle = "#000000";
	
			while( an = tool.conf.anno.shift() ) {
				el = an.shift();
				tool.conf.context.beginPath();
				tool.conf.context.moveTo(el.x, el.y);
				while( el = an.shift() ) {
					tool.conf.context.lineTo(el.x,el.y);
					tool.conf.context.stroke();
				}
				tool.conf.context.closePath();
			}
			tool.conf.anno = [];
			tool.conf.anno_counter = 0;
		},

		mousedown: function (ev,cb) {
			var tool = this;
			if( true == ev.ctrlKey ) { // pressing CTRL and clicking into canvas will clear it.
				console.log("canvas deleted!");
				tool.conf.context.clearRect(0, 0, tool.conf.canvas.width, tool.conf.canvas.height );
				return;
			} 
			if( true == ev.shiftKey ) { // pressing SHIFT and clicking into cnavas will restore the recorded annotations.
				console.log("captured annotation redrawn");
				tool.redrawMyAnnotation();
				return;
			}
			// this is the drawing section. When clicking in the canvas the drawing will be initiated. 
			// The drawing itself is done once in 100ms, so mot every tiny movement of the mouse 
			// translates into freehand element.
			tool.conf.context.globalAlpha= "1.0";
			tool.conf.context.strokeStyle = "#000000";
			tool.conf.context.beginPath();
			tool.conf.context.moveTo(ev._x, ev._y);
			tool.conf.lastX = ev._x;
			tool.conf.lastY = ev._y
			tool.conf.started = true;
			tool.conf.anno[tool.conf.anno_counter] = [];
			tool.conf.intervalID = setInterval( cb, 100 );
//			tool.conf.intervalID = setInterval( "opentext.tools.data.pencil.doLine()", 100 );
//			tool.conf.intervalID = setInterval( cb.call(tool), 100 );
		},

		mousemove: function (ev) {
			var tool = this;
			if (tool.conf.started) {
				tool.conf.lastX = ev._x;
				tool.conf.lastY = ev._y
			}
		},

		doLine: function() {
			var tool = this;
			console.log("painting");
			tool.conf.context.lineTo(tool.conf.lastX, tool.conf.lastY);
			tool.conf.context.stroke();
			tool.conf.anno[tool.conf.anno_counter].push( { "x":tool.conf.lastX, "y":tool.conf.lastY } ); 
		},
		
		// This is called when you release the mouse button.
		// stop recording the annotation coordinates and stop drawing.
		// increase the annotation counter so next time a new annotation
		// gets recorded.
		mouseup: function (ev) {
			var tool = this;
			if (tool.conf.started) {
				tool.conf.context.closePath();
				tool.mousemove(ev);
				tool.conf.started = false;
				clearInterval(tool.conf.intervalID);
				tool.conf.anno_counter++;
			}
	  }
	}
};
// >>>

// This global painting object works like a drawing pencil which tracks the mouse movements.
// The mouse movement is stored in a contained inside the object itself. The data
// gets removed by each initilization cycle and by each use.
//function	FreehandTool ( cnv, ctx ) {
//var FreehandTool = function( cnv, ctx ) {
opentext.drawingTools.FreehandTool2 = function( cnv, ctx ) {
// <<<
		  var tool = this;
		  this.started = false;
		  this.canvas = cnv;
		  this.context = ctx;
		  this.anno = []; // contained for annotation. Technically it is array of arrays. 
		  this.anno_counter = 0; // count how many annotations were put on the drawing.
		
		  // This method restored the saved annotation and put them back in the drawing. Attantion, 
		  // this method is destructive and you can read the local container just one. I is a poor
		  // man example using push() and shift() array access control, which make it a LIFO queue.
		  this.redrawMyAnnotation = function() {
				var an;
				var el;
				if( typeof tool.anno == "undefined" )
					return;

				tool.context.globalAlpha= "1.0";
				tool.context.strokeStyle = "#000000";

				while( an = tool.anno.shift() ) {
					el = an.shift();
					tool.context.beginPath();
					tool.context.moveTo(el.x, el.y);
					while( el = an.shift() ) {
						tool.context.lineTo(el.x,el.y);
						tool.context.stroke();
					}
					tool.context.closePath();
				}
				tool.anno = [];
				tool.anno_counter = 0;
			};

		  // This is called when you start holding down the mouse button.
		  // This starts the pencil drawing.
		  // For simplisity reasons, this function also impletemts two extra 
		  // operation:
		  // 1) clean the drawing canvas
		  // 2) place the recored annotation on the canvas.
		  this.mousedown = function (ev, cb) {
				if( true == ev.ctrlKey ) { // pressing CTRL and clicking into canvas will clear it.
					console.log("canvas deleted!");
					tool.context.clearRect(0, 0, tool.canvas.width, tool.canvas.height );
					return;
				} 
				if( true == ev.shiftKey ) { // pressing SHIFT and clicking into cnavas will restore the recorded annotations.
					console.log("captured annotation redrawn");
					tool.redrawMyAnnotation();
					return;
				}
				// this is the drawing section. When clicking in the canvas the drawing will be initiated. 
				// The drawing itself is done once in 100ms, so mot every tiny movement of the mouse 
				// translates into freehand element.
				tool.context.globalAlpha= "1.0";
				tool.context.strokeStyle = "#000000";
				tool.context.beginPath();
				tool.context.moveTo(ev._x, ev._y);
				tool.lastX = ev._x;
				tool.lastY = ev._y
				tool.started = true;
				tool.anno[tool.anno_counter] = [];
//				tool.intervalID = setInterval( "opentext.tools.data.pencil.doLine()", 100 );
				tool.intervalID = setInterval( cb, 100 );
		  };
		
		  // This function is called every time you move the mouse. Obviously, it only 
		  // draws if the tool.started state is set to true (when you are holding down 
		  // the mouse button).
		  this.mousemove = function (ev) {
			 if (tool.started) {
				tool.lastX = ev._x;
				tool.lastY = ev._y
			 }
		  };

		  // This is the drawing method, is not called each time the mousemove event fires,
		  // just every 100 ms. Otherwise the datastream generated for freehand annotation
		  // would be flooding the buffer ...
		  this.doLine = function() {
				console.log("painting");
				tool.context.lineTo(tool.lastX, tool.lastY);
				tool.context.stroke();
				tool.anno[tool.anno_counter].push( { "x":tool.lastX, "y":tool.lastY } ); 
		  }
		
		  // This is called when you release the mouse button.
		  // stop recording the annotation coordinates and stop drawing.
		  // increase the annotation counter so next time a new annotation
		  // gets recorded.
		  this.mouseup = function (ev) {
			 if (tool.started) {
				tool.context.closePath();
				tool.mousemove(ev);
				tool.started = false;
				clearInterval(tool.intervalID);
				tool.anno_counter++;
			 }
		  };
	}
// >>>

// Data Beans - static object keeping the configuration parameters for
// across the application namespace. As a static object the initial
// structure is set up at startup and can keep the data without
// calling the constructor.
//
// This strategy defines data bean inside the namepsace opentext.
// The bean can store arbitrary data and give them back to callee.
// The immediate function pattern is used to define the Bean
// Container.
opentext.beans = {};
opentext.beans.webviewer = (function() {
//<<<
	var me = this;
	me.conf = {};	
	return {
		conf: this.conf,
		set: function( pars ) {
//			console.log('opentext.beans.set() called');
			opentext.tools.merge( this.conf, pars );
//			for (var i in me.conf)
//				console.log( '	' + i + ' = ' + me.conf[i] + " is of type " + typeof me.conf[i]);
		},
		get: function( n ) {
//			console.log('opentext.beans.get(' + n + ') enter');
			if( typeof conf[n] === 'undefined' ) {
				console.warn( 'opentext.beans.webviewer Bean does not contain property: ' + n ); 
				return 'undefined';
			}
//			console.log('opentext.beans.get(' + n + ') returning ' + conf[n] );
			return conf[n];	
		}
	};
}());
//>>>

// Common tools inside the application namespace.
// Used pattern - immediate function - makes sure that the
// opentext.tools is a pointer to object having an public API.
// The pattern produces a static object, accessible across the
// application namespace.
opentext.tools = (function() {
//<<<
	var me = this;
	var bean = opentext.beans.webviewer;
	var a,a0;
	return {
		data: this.data,

		getVal: function( url, pattern ) {
			var tmp;
			console.log( 'opentext.tools.getVal() search for pattern = ' + pattern + ' in URL = ' + url );
			tmp = url.slice(url.indexOf("&") + 1);
			a = tmp.split("&");
			if( typeof a === 'object' && a.length > 0 ) {
				for( var it in a ) {
					if( typeof a[it] !== 'undefined' ) {
						a0 = a[it].split("=");
						if( a0[0] === pattern ) {
							tmp = a0[1];
							break;
						}
					}
				}
			} else {
				console.warn( 'opentext.tools.getVal(): the source is not an array. Cannot find a pattern' );
				tmp = "";
			}

			console.log( 'opentext.tools.getVal() found pattern = ' + pattern + ' = ' + tmp );
			return tmp;
		},

		encodeurl: function( str ) {
			var tmp = encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
			console.log( 'opentext.tools.encoderurl input = ' + str );
			console.log( 'opentext.tools.encoderurl result = ' + tmp );
			return tmp;
		},

		decodeHTML: function( str ) {
			var tmp = str.split("&#034;").join('"'); 
			return tmp;
		},

		merge: function(a,b) {
			console.log('opentext.tools.merge() called');
			for( var i in b )
				if(b[i] !== undefined)
					a[i] = b[i];
		},

		notificationDestroy: function() {
			var vc = document.getElementById( bean.get( 'wall' ) );
			var o = document.getElementById( 'notification_box' );
			vc.removeChild( o );
		},

		processJSONRequest: function() {
			var jsonDoc = null;
			var o = {};
			var wtxt;
			console.log( "Request fired for response parsing JSON" );

			if (req.readyState == 4 && req.status == 200) {
				console.log( "INFO: Request fired and response came back with status 200" );

				jsonDoc = req.responseText; 
				if( jsonDoc ) {
					wtxt = jsonDoc.replace( /.*\<json_tag\>/m, "" );
					wtxt = wtxt.replace( /\<\/json_tag\>/m, "" );
					wtxt = opentext.tools.decodeHTML( wtxt ); 
					o = JSON.parse(wtxt);
					opentext.beans.webviewer.set( o );
					opentext.tools.showDocumentProperties();
				} else {
					console.log( "ERROR: cannot retrieve the elements from JSON structure" ); }
			} else if ( req.readyState == 4 && req.status == 0 ) {
				opentext.tools.notification( opentext.localization.MSGID001, 'loading loading_red', 4000 );
			} else {
			console.log( 'XMLHttpResponse: state=' + req.readyState + ', status=' + req.status );
		  }
		},

		processXMLRequest: function() {
			var xmlDoc = null;
			var o = {};
			console.log( "INFO: Request fired and response came back with status 200" );

			if (req.readyState == 4 && req.status == 200) {
				console.log( "INFO: Request fired and response came back with status 200" );

				xmlDoc = req.responseXML;
	
				if( xmlDoc ) {
					var arr = xmlDoc.childNodes[1].childNodes;
	
					if( arr ) {
						for( var i = 0; i< arr.length; i++ ) {
							if( arr[i].nodeName.toLowerCase() == "pagecount" ) {
								o.pageCount = parseInt( arr[i].textContent, 10 );
								console.log( "INFO: retrieved pagecount = " + o.pagecount );
							}
							if( arr[i].nodeName.toLowerCase() == "hasnotes" ) {
								o.hasNotes = arr[i].textContent;
								console.log( "INFO: retrieved hasNotes = " + o.hasnotes );
							}
						}
						opentext.beans.webviewer.set( o );
					} else {
						console.log( "ERROR: cannot retrieve the elements from XML structure" );
						opentext.tools.notification( opentext.localization.MSGID002, 'loading loading_red', 4000 );
					}
				} else {
					console.log( "ERROR: cannot retrieve the elements from XML structure" );
					opentext.tools.notification( opentext.localization.MSGID002, 'loading loading_red', 4000 );
				}
			} else if ( req.readyState == 4 && req.status == 0 ) {
				opentext.tools.notification( opentext.localization.MSGID001, 'loading loading_red', 4000 );
			} else {
			console.log( 'XMLHttpResponse: state=' + req.readyState + ', status=' + req.status );
		  }
		},
		
		getBrowserDimension: function () {
			var dimension = { pageWidth: 0, pageHeight: 0, windowWidth: 0, windowHeight: 0 };

			if (window.innerHeight && window.scrollMaxY) {	
				dimension.pageWidth = document.body.scrollWidth;
				dimension.pageHeight = window.innerHeight + window.scrollMaxY;
			} 
			else if (document.body) {
				if (document.body.scrollHeight > document.body.offsetHeight) {
					dimension.pageWidth = document.body.scrollWidth;
					dimension.pageHeight = document.body.scrollHeight;
				} 
				else {
					dimension.pageWidth = document.body.offsetWidth;
					dimension.pageHeight = document.body.offsetHeight;
				}
			}

			if (window.innerHeight) {
				dimension.windowWidth = window.innerWidth;
				dimension.windowHeight = window.innerHeight;
			} 
			else if (document.documentElement && document.documentElement.clientHeight) {
				dimension.windowWidth = document.documentElement.clientWidth;
				dimension.windowHeight = document.documentElement.clientHeight;
			} 
			else if (document.body) {
				dimension.windowWidth = document.body.clientWidth;
				dimension.windowHeight = document.body.clientHeight;
			}			 

			if (dimension.pageWidth < dimension.windowWidth) dimension.pageWidth = dimension.windowWidth;
			if (dimension.pageHeight < dimension.windowHeight) dimension.pageHeight = dimension.windowHeight;

			return dimension;
		},

		buildRibbon: function() {
			console.log( 'opentext.tools.buildRibbon(): enter' );
			var data = {
				stamps: ['Approved finance','Rejected finance','Approved Administration','Rejected Administration','Postponed'],
				users: ['martinme','adelano','johndo','jakamutota','pivozjednoty','mineralka','kafeodzida'] 
			};
			var html = new EJS({url: 'scripts/WebViewer_Ribbon.ejs'}).render(data)
	
			$('div.mainContainer').empty();
			$('div.mainContainer').append($(html));
			$('div.mainContainer').Ribbon({ theme: 'windows7_no_orb' });
			console.log( 'opentext.tools.buildRibbon(): leave' );
		}
	};
}());
//>>>

opentext.drawing = (function() {
//<<<
	var me = this;
	var bean = opentext.beans.webviewer;
	me.tools = {};
	tools.pencil = {};
	return {
		tools: this.tools,
	};
}());
//>>>

// WebViewer Constructor.
opentext.WebViewer = function(opts) {
//		  <<<
	var me = this;

	me.data = {
		cfg : {
			"currentPage": 0,
			"imageWidth": 0,
			"useZoomer": false,
			"anno": 'anno-id-01'
		},
		drawingTools: {
			"pencil" : null,
			"highlighter" : null
		}
	};

	try {
		opentext.tools.merge(me.data.cfg, opts);
		opentext.beans.webviewer.set( me.data.cfg );
	} catch( e ) {
			alert( e.name + ": " + e.message );
			throw( { name: 'opentext.WebViewer.constructor', message: e.message } );
	}

	if( opts.localization_test == true ) alert( opentext.localization.MSGID000 );
};
//>>>

// Class definition for the object WebViewer. The constructor must be
// called before the WebViewer object can be used. The constructor
// takes parameters that control the view.
//
// The constructor is called as a part of this library and global
// variable ww is exposed to calling HTML markup.
opentext.WebViewer.prototype = {
//<<<
		run: function() {
//<<<
			var me = this;
			var bean = opentext.beans.webviewer;

			console.log( 'opentext.WebViewer.run() enter' );

			opentext.tools.buildRibbon();

			me.data.cfg.mainImage = bean.get('user');

			var o = {};
			o.zoomTimer = 0;
			bean.set( o );

			console.log( 'opentext.WebViewer.run() exit' );

			$('#zoom-in').bind('mousedown', function(e) {
				console.log('mouse down');
				gZoomTimer = setInterval( function() {
					console.log('zooming in');
					var w = parseFloat($('#cont_id_01').css('width'));
					var h = parseFloat($('#cont_id_01').css('height'));
	//				var m = parseFloat($('#cont_id_01').css('margin-left'));
					var c = parseFloat($('div.page_container').css('width'));
					var m = ( c - w ) / 2;
					
					var o = w;
					var d;
					w *= 1.03;
					h *= 1.03;
					d = (w - o ) / 2;
					m = m - d;
					m = ( m > 0? m: 0 );
					var mx = w / 1112;
					var hc = h + 10;
					
					var tX = (((( 1112 * mx ) - 1112 ) / 2 ) + m ) / mx;
					var tY = ((( 1440 * mx ) - 1440 ) / 2 )  / mx;
	
					$('div.document_container > div').css('height', hc + 'px' );
					$('div.document_container > div > div.annotations_view').css('-webkit-transform', 'scale(' + mx + ') translateX(' + tX + 'px) translateY(' + tY + 'px)' );
					$('div.document_container > div > div.page_view').css('width', w + 'px').css('height', h + 'px').css('margin-left', m + 'px').css('margin-right', m + 'px' );
					$('div.document_container > div > div.page_view > svg').removeAttr('width').removeAttr('height').attr('width', w + 'px').attr('height', h + 'px' );
					$('div.document_container > div > div.page_view > svg > g[transform]').attr('transform', 'matrix(' + mx + ',0.0,0.0,' + mx + ',0.0,0.0)');
	
					/* top/bottom scrolling is always used */
					var current = $('div.document_container').scrollTop();
					var ratio = w / o; 
					current *= ratio; // trick for keeping the mid screen mid point in the middle.
					console.log("Current=" + current );
					console.log("Current=" + current );
					$('div.document_container').scrollTop(current);
	
					/* use scrolling when the content overflows right/left margin */
					if( m == 0 ) {
						console.log('trigger scroll!');
						m = ( w - c ) / 2;
						$('div.document_container').scrollLeft(m);
					}
				}, 30 );
			});				

			$('#zoom-in').bind('mouseup', function(e) {
				console.log('mouse up');
				window.clearInterval(gZoomTimer);
			});				

			$('#zoom-out').bind('mousedown', function(e) {
				console.log('mouse down');
				gZoomTimer = setInterval( function() {
					console.log('zooming in');
					var w = parseFloat($('#cont_id_01').css('width'));
					var h = parseFloat($('#cont_id_01').css('height'));
	//				var m = parseFloat($('#cont_id_01').css('margin-left'));
					var c = parseFloat($('div.page_container').css('width'));
					var m = ( c - w ) / 2;
					var o = w;
					var d;
					w *= 0.97;
					h *= 0.97;
					d = (w - o ) / 2;
					m = m - d;
					m = ( m > 0 ? m: 0 );
					var mx = w / 1112;
					var hc = h + 10;

					var tX = (((( 1112 * mx ) - 1112 ) / 2 ) + m ) / mx;
					var tY = ((( 1440 * mx ) - 1440 ) / 2 ) / mx;
	
//					$('div.document_container > div').css('height', hc + 'px' );
//					$('div.document_container > div > div > svg').removeAttr('width').removeAttr('height').attr('width', w + 'px').attr('height', h + 'px' );
//					$('div.document_container > div > div').css('width', w + 'px').css('height', h + 'px').css('margin-left', m + 'px').css('margin-right', m + 'px' );
//					$('div.document_container > div > div > svg > g[transform]').attr('transform', 'matrix(' + mx + ',0.0,0.0,' + mx + ',0.0,0.0)');

					$('div.document_container > div').css('height', hc + 'px' );
					$('div.document_container > div > div.annotations_view').css('-webkit-transform', 'scale(' + mx + ') translateX(' + tX + 'px) translateY(' + tY + 'px)' );
					$('div.document_container > div > div.page_view').css('width', w + 'px').css('height', h + 'px').css('margin-left', m + 'px').css('margin-right', m + 'px' );
					$('div.document_container > div > div.page_view > svg').removeAttr('width').removeAttr('height').attr('width', w + 'px').attr('height', h + 'px' );
					$('div.document_container > div > div.page_view > svg > g[transform]').attr('transform', 'matrix(' + mx + ',0.0,0.0,' + mx + ',0.0,0.0)');
	
					/* top/bottom scrolling is always used */
					var current = $('div.document_container').scrollTop();
					var ratio = w / o; 
					current *= ratio;
	//				current *= (ratio * 0.995);
					$('div.document_container').scrollTop(current);
	
					if( m == 0 ) {
						console.log('trigger scroll!');
						m = ( w - c ) / 2;
						$('div.document_container').scrollLeft(m);
					}
				}, 30 );
			});				

			$('#zoom-out').bind('mouseup', function(e) {
				console.log('mouse up');
				window.clearInterval(gZoomTimer);
			});				

			$('#anno-id-01').bind('mouseup', function(e) {
				console.log('mouseup even on Canvas caught');
				ev_canvas(e);
			});
			$('#anno-id-01').bind('mousedown', function(e) {
				console.log('mousedown even on Canvas caught');
				ev_canvas(e);
			});
			$('#anno-id-01').bind('mousemove', function(e) {
				console.log('mousemove even on Canvas caught');
				ev_canvas(e);
			});
	
			var canvas = document.getElementById( 'anno-id-01' );
					
			// Check the element is in the DOM and the browser supports canvas
			if(!(canvas && canvas.getContext)) {
				return;
			}
			
			// Initaliase a 2-dimensional drawing context
			var context = canvas.getContext('2d');
	
			console.log('WebViewer:run(): creating the freehandtool for canvas' + canvas + ' with context ' + context );
//			opentext.tools.data.pencil = new FreehandTool( canvas, context );
//			opentext.tools.data.pencil = new opentext.drawingTools.FreehandTool2( canvas, context );
			opentext.drawing.tools.pencil = new opentext.drawingTools.FreehandTool2( canvas, context );
		}
//>>>
};
// >>>

var gZoomTimer;

$(document).ready( function() {
	opentext.ww = new opentext.WebViewer( { localization_test: true });
	opentext.ww.run();
});
